perm filename ABBIS3[1,RWF]1 blob sn#728185 filedate 1983-10-26 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00012 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	***Goes after Iteration***
C00005 00003	Example:    FOR I: = 1 TO 4 DO WRITE(I * I)
C00006 00004	Because of the similarity of the rectangles to contour lines on a map, this
C00007 00005	The Best is the Enemy of the Good
C00012 00006	Arrays
C00017 00007	Programming Cliches
C00021 00008	Discrete Simulation
C00029 00009	Exercise in Conditional Programming.
C00031 00010	Fancy Stuff, no more credit, lots more work:
C00033 00011	Monte Carlo Methods
C00039 00012	It is not ordinarilyt possible to generate truly random numbers on a
C00044 ENDMK
C⊗;
***Goes after Iteration***

-Human Execution of Computer Programs-

A computer program can be executed by a human.  There are many good
reasons for executing a program "by hand", including:
	(1) A program may be desk-checked on a small problem to which the
	    answer is known.   Unexpected intermediate results show likely 
	    locations for errors.

	(2) A program written by another person can be hand executed to get
	    insight into the logic of its design.

To hand-execute an iteration of the form FOR I:= A TO B DO S:
	(1) Evaluate A and B getting numerical values N↓A and N↓B

	(2) Write down FOR I:= N↓A TO N↓B DO

	(3) Draw a vertical rectangle, leaving it open at the bottom until
	    you know how much room the execution will take.

	(4) Inside the rectangle, write I = N↓A

	(5) If I <= N↓B, hand-execute command S; otherwise go to step 7.
	    If S is itself an iteration its execution record will be a
	    second rectangle inside the first one.

	(6) Write I = (one greater than the previous value) and return to
	    step 5. 

	(7) Close off the bottom of the rectangle, and write "I = ?", to
	    show that after completion of an iteration, the iteration variable 
	    is left with an unspecified value.

Example:    FOR I: = 1 TO 4 DO WRITE(I * I)

	FOR I: = 1 TO 4 DO
	I = 1
	WRITE(I * I)		1
	I = 2
	WRITE(I * I)		4
	I = 3
	WRITE(I * I)		9
	I = 4
	WRITE(I * I)		16
	I = 5

	I = ?

Example:    FOR I: = 1 TO 3 DO
		FOR J: = I + 1 TO 3 DO
			WRITE(I * J)

	FOR I: = 1 TO 3 DO
	I = 1
	FOR J: = 2 TO 3 DO
		J = 2
		WRITE(I * J)		2
		J = 3
		WRITE(I * J)		3
		J = 4
		J = ?

	I = 2
	FOR J: = 3 TO 3 DO
		J = 3
		WRITE(I * J)		6
		J = 4
		
		J = ?

	I = 3
	FOR J: = 4 TO 3 DO
		J = 4
		(no other action)
		
		J = ?
	I = 4
I = ?

Because of the similarity of the rectangles to contour lines on a map, this
method is called the -contour model- of program execution.  As we go deeper
into Pascal, we will find other features of the language that introduce
contour lines, each with its own rules for filling in the boxes.

The Best is the Enemy of the Good

A frequent task in computing is to find the best, for some purpose, of a
finite set.  If  f(i) is my predicted profit from making i widgets this
year, and my factory can't make more than 1000 of them in a year, I need to
know the value of i between 1 and 1000 that makes f(i) the largest.  I may
also have more than a passing interest in the value f(i) has for that value
of i.

The naive way to do the problem is to test each value of i in turn, against
all the other numbers, printing i if it wins all these contests.  In
outline, here is the program:

	FOR I:=1 TO 1000 DO
		BEGIN
		LOSSES:=0;
		FOR J:=1 TO 1000 DO
			IF F(I) < F(J) THEN
				LOSSES:=LOSSES + 1;
		IF LOSSES=0 THEN
			WRITELN(I, F(I))
		END

This program has several problems.  It potentially prints several equally
good values of i, though that isn't necessarily bad.  It takes far too much
time, executing some operations a million times when it could be
redesigned not to do anything more than a thousand times.  The faster
program is also shorter.

The problem with the program above is that it is conducting a contest among
the numbers from 1 to 1000 as if it were a round robin tournament, where
everyone plays a game against everyone else.  To find the best player using
the fewest games, it is far more efficient to use a knockout tournament,
where losers are eliminated from further play.  A program can run through
the numbers from 1 to 1000, keeping track only of the current number, and of
that previous number that beat all the others.  Using a variable BESTSOFAR
to keep the current winner, the program is:

	BEGIN
	BESTSOFAR:=1;
		FOR I:=2 TO 1000 DO
			IF F(I) > F(BESTSOFAR) THEN
				BESTSOFAR:=1;
	WRITELN(BESTSOFAR, F(BESTSOFAR))
	END.

A slight improvement in efficiency can be made by not discarding the best
value of f so far:

	BEGIN
	BESTSOFAR:=1;
	FBEST:=F(1);
	FOR I:=2 TO 1000 DO
		BEGIN
		FI:=F(I);
		IF FI > FBEST THEN
			BEGIN
			FBEST:=FI;
			BESTSOFAR:=I;
			END
		END
	END


The same pattern can, of course, be used to find the smallest, by changing
">" to "<".  We can find the first or last number that meets a condition by
similar programs.  Say we want to find the largest number between 1 and
1000 that meets a certain test.  Here are several methods:

(1)	LARGEST:=0;
	FOR I:=1 TO 1000 DO
		IF TEST(I) THEN
			LARGEST:=I;
	IF I > 0 THEN WRITELN(`LARGEST:' I)
	ELSE WRITELN(`NO NUMBER SATISFIES THE TEST')

(2)	I:=1000;
	WHILE (I > 0) AND NOT TEST(I) DO
		I:=I-1;
	IF I > O, etc.

(3)	FOR I:=1000 DOWNTO 1 DO
		IF TEST(I) THEN
		BEGIN LARGEST:=I
		GO TO 99;
		END
	WRITELN(`NO NUMBER SATISFIES THE TEST');
	GO TO 100;
	99: WRITELN(`LARGEST:' LARGEST)
	100: END.

Arrays

Pascal, with almost every programming language, contains builtin functions the
programmer can not change, like the square root and trigonometric
functions.  The world also contains functions that change with time, like
COHORT(A) = the number of people of age A, or INCOMETAX(I), the income tax
on I dollars.  Such functions are represented in programming languages by
arrays: tables which store the value of the function for each argument in a
certain range.  The allowed operations include not only finding the value
of the function on any argument within range (a ←value access← to the
array) but also specifying a new value of the function on any argument
within range( a ←reference access← to the array)

For example, a program to read 150 numerical data from a file and print
them numbered in three columns, can begin by reading each datum and letting
it be the value of the array for one argument.  After all have been read
and stored, the program finds the values stored in the array, in the
correct order for printing.  The program, in outline, is this:

	(Declarations)
	BEGIN
	FOR I:=1 TO 150 DO
		READ(A[I]);
	FOR J:=1 TO 50 DO
		WRITELN(J, A[J],J+50,A[J+50],J+100,A[J+100])
	END.

If A is an array with index type T←1 and value type T←2, and I is an
expression of type T←1, we can use A[I] to mean the value of A for the
argument I.  This program fragment:

	S:=0;
	FOR J:=0 TO 2 DO
		S:=S+A[J+1];
	WRITE(S)

prints the value of A(1) + A(2) + A(3).  If A[I] appears in an assignment
context, a new value is given to A for the argument I; after executing this
program fragment:

	FOR I:=1 TO 3 DO
		IF I=2 THEN A[I]:=3.0
		ELSE READ(A[I])

with the input file  5.7 6.9
we will have A(1) = 5.7, A(2) = 3.0, A(3) = 6.9

In Pascal, an array type is of the form
	
	ARRAY[T←1] OF T←2

where T←1 is the argument type, and T←2 the result type.  The argument type
must be a subrange.  The result type can be any type for which assignment
is possible, ie. any non-file type.  An array is declared in the same way a
program variable is, using an array type.  The declaration

	VARIABLE A: ARRAY[1..10] OF REAL

declares A as an array with integer indices in (1,10), with real number
values.  

An array could be declared

	VARIABLE CODE: ARRAY[`A'..`Z'] OF CHAR

Such an array could be used to store a function from letters to letters for
decoding a substitution cipher.

Arrays may have more than one argument.  An array to hold a tax table for
specified income (in $1000s) and family size would be declared:

	VARIABLE TAXTBL: ARRAY[1..2000, 0..20] OF INTEGER

or giving the array type a name of its own,

	...
	...
	TYPE TXTBTY = ARRAY[1..2000, 0.20] OF INTEGER;
	...
	...
	VARIABLE TXTBL:TXTBTY
	...
	...

Programming Cliches

In ordinary language, there are phrases or sentences we use over and over
again, like "Do you swear to tell the truth, the whole truth and nothing
but the truth?", or "Ham on rye, hold the mustard."  We know that they
serve their function precisely, and we save effort by not having to
reinvent them constantly.  Such cliches are found in computer programs too.
This book presents a number of them; they are worth memorizing.  Here is
one to exchange the contents of two variables.

To exchange the places of two cars in parking spaces, we must have a third
place to put a car.  If car A is in space X and car B is in space Y, we
move A from space X to a third space T, B from space Y to space X, and A
from space T to space Y.  In programs, we don't give numbers names that
follow them around, like "car A" above; we name them by saying where they
are.  The program fragment, analogous to the car swap, that exchanges the
numbers in variables X and Y is

	T:=X;
	X:=Y;
	Y:=T

where X,Y, and T are variables of the same type, and T is what we call a
temporary variable; that is, the value put into it is used at once and
never again.

Another cliche is used to find the value of i for which f(i) is a maximum
(A<=i<=B); 
	MAX:=F(A);	(*SMALLEST POSSIBLE VALUE*)
	LOCMAX:=A;
	FOR I:=A+1 TO B DO
		IF F(I) > MAX THEN
			BEGIN
			MAX:=F(I);
			LOCMAX:=I
			END;

This cliche embodies the insight that finding the largest of a finite set
does not require that every element be compared to every other.

Priority Cliches

If a program must choose between several courses of action, often there is
a priority order; if the conditions for several actions are all true, the
program must perform the action of highest priority.

Example:

IF heart attack THEN administer CPR
ELSE IF house on fire THEN call 911
ELSE IF hungry THEN go for food
ELSE IF unprepared THEN study.

Discrete Simulation

Assume we have the schedule fo all daily airline flights among a group of
cities.  We are planning a guide for air travelers which shows, for each
origin and destinations city, not only the direct flights, but connections
that reach the destination by one or more changes of planes.   We will
include a connection if it is the fastest way to go for someone arriving at
the airport just in time to emplane on it.  To simplify matters, we assume
all flights are daily, and that changes of plane can be carried out
instantly; in the real world, the problem is much more complex.

Before trying to program the problem, let's look at an algorithm for it.
We will simulate a time period in which a roup of travelers starts out on
every flight.  Whne the group on one flight reaches a city, we check if
any other travelers from the same original point of departure started later
and reached their current city earlier; if so, we make no further use of
this group.  If, however, the group has used good connections so far, as
shown by not having been outraced to the current city, we record this
itinerary in the list of connections.  We also split them up, and let some
of them continue on each flight out of their current city.  We continue thi
process for at least twent-four hours; in fact, as long as there are still
travelers who started during the original twenty-four hours, we must keep
the entire process going to check for alternative routes.

When we simulate the events of this scenario, which are arrivals and
departures at airports, we have to do it in chronological order.
Otherwise, when we find traveler A arriving at city B from city C, we may
not yet know that traveler D, by a different route, can leave city C
earlier and reach city B sooner.  To make things happen in chronological
order, we will keep a master list of all future events that are certain to
happen, sorted (i.e., arranged in increasing order) by the time at which
the event will happen.  When we make an event happen, it will always be the
first on the master list.  As we simulate an event, we put on the master
list all future events it implies.  This technique is the general method
for what are called ←discrete simulation← problems, whether they concern
air or road traffic, serving custoemrs in a bank, or .... .

In our particular problem, we start off by putting all scheduled departures
on the masters list, and then "start the clock running".  The first event
drawn from the master list is the first flight departure of the day.  We
put on it a group of travelers, represented by their city and time of
origin, and insert their predicted arrival at another city into the master
list.   We then go on to the next event from the master list. Notice that
the "clock" of our simulation is not a counter; it only shows those times
at which some actual event happens.

As we continue through the simulated day, we begin to process arrivals.
We need to be able to tell if these arrivals are the completions of good
connections, so we keep track of the starting time of the most recent good
connection between each pair of cities.  When we check travelers in who
began in city A and arrive at city B, if we find that some other travelers
have already arrived from city A who began later, we may ignore the current
arrivals; theirs is not the best connection.  The record keeping is done
with an array of starting times, indexed by the numbers of the origin and
destination city.

As we proceed through the simluation, we eventually begin to process
travelers who have changed places several times; we need to keep track of
their complete itinerary.  We can do this by building up a list of flights,
each of which shows city and time of origin, and the  cities and times of
one leg of a trip.  If it is not the first leg of the trip, it also shows
the index of the immediately preceding leg of the trip.  Each traveler is
represented, then, by the index of the last leg of his trip; we can trace
back through the earlier legs if needed, e.g. for eventual output of
connections.   We can't stop the simulation until all travelers who began
during the first twenty-four hours are gone.  We can keep count of how many
there are, and stop when the count is zero and the clock is past the first
day.

We can assume that all departure and arrival times are given on a
twenty-four hour clock.


***********
ADD MORE

Exercise in Conditional Programming.

A hand of cards, in the game of bridge, is evaluated for ←high card points←
(HCP) on the scale A=4, K=3, Q=2, J=1.  The ←distributional value← is 3 for
each void suit, 2 for each one-card suit, 1 for each 2-card suit, and 1 for
each card beyond the fifth in a suit.  The following hand has 11 HCP and a
distributional value of 4 for a ←total valuation← of 15 points.

	SA SJ S9 S3
	H7
	DQ DJ D10 D8 D5 D2
	CK C9

A hand with distributional value no more than 1 is called balanced.

Opening bids in bridge can be made according to these rules:
Balanced Hands (Use HCP)
	16 to 18 HCP: Bid 1NT
	22 to 24 HCP: Bid 2NT
	25 to 27 HCP: Bid 3NT
	Other ranges: bid as if unbalanced

Unbalanced Hands(Use total evaluation)
	21 points or more: Bid 2C
	6-12 points and an 8 card suit:  Bid 4 of the suit.
	6-12 points and an 7 card suit:  Bid 3 of the suit.
	6-12 points and a 6 card suit; not clubs: Bid 2 of the suit.
	13  points or more, no other bid:  Bid 1 of best suit.
	No other satisfactory bid: "Pass".

The best suit is the longest; if two are equally long, bid the higher one
(Spades > Hearts > Diamonds > Clubs).

Fancy Stuff, no more credit, lots more work:

With two non-adjacent best suits, bid the lower one.  Restrict the bid of 3
or 4 of a suit to defenseless hands  (no more than 3 HCP in the other
suits).  Use the 3NT bid to show 5 or more cards in each minor suit
(diamonds, clubs) with total evaluation of 13 or more.  Unbiddable suits
include 4-card majors, all 4-card suits of two HCP or less.

Your program should read a file where each data line looks like this
example:

	D8 CK H7 DQ C9 DT S9 S3 D2 D5 SJ SA DJ. (DT is the 10 of diamonds).

It should print a correct bid for each hand.  The last line is the sentinel
`STOP'. 

Test your program on file            and files of your own design.  The
file             will be made available for your graded run at (time)  on
(date).  We do this intentionally, to enforce systematic testing.

Monte Carlo Methods

There is no part of a computer that resembles dice, cards, a spinning coin,
or any other such device prized for its randomness.  Still, at times we
want to use a computer to study the behavior of systems that do contain
random elements.  The telephone company tries to ensure that its circuits
will accomodate not only average traffic, but most of the occasional
"random" peaks.  Similar studies can be made of vehicle traffic, customers
queueing (yes, it's an English Word) in a bank, or evolution of bird
species.  Often there seems to be no better way to analyze such partially;
random systems than to simulate them: to write computer programs that
behave as they do, including their random elements.

Just as all polynomials can be built up by addition and multiplication, so
can most random phenomena be built up from a process that picks a random
numbers.  Ordinarily, the random number is picked fro ma certahprβKπ;>)1β''_4+C␈≠O'f)β[πg+↔MβNqβS#∂!βKπv;∃βπ⊗)β↔G.33eπ≠Cπ∂.!1βπv!βS#/IβπK*βπ31ε+GWπfcd4+fK/↔3Jq↓α¬πβK?∂/≠MβSFQβ∪}+MβSFKMβ←*β∂π3bβ¬α␈⊗;∪?jβ;W7⊗+Iβ∨.s↔Kπ&{J⎇9αα'P4Vk'∨#"βC'∂Zβπ9βNsS↔∨/⊃β↔';↔↔9β↓βπ;"α6εbLrQ1β␈⊃β¬β⊗+π1βw+7↔∩β↔S>+↔9↓αβπ;⊂hQEmβ.KS#↔∩β←?Wf!β∃π+O↔≠.a9↓αNqβ¬β≡{7CW&+I1β
βKπ;&{5β;.k↔Iε;↔;↔⊗S?Iπ;'30hSSgCN≠π33Jβ∃β
β≠W;∨#'?9ε{IβC⊗{∂↔∪/∪∃βSFQβK/#WK;~β¬β[∞cW∃β∞≠∂?K&K;≥β&yβS#(h+KWf+Mβπ⊗{[∃8hP4*3/!∨Mβ∂≠OW7*β←∃βF[∃β
βKπ;&{5β;.k↔Iε;↔;↔⊗S?IπβK?∂.#WK∃¬∩ε:∩|jJ⊗εbaβ←#N≠ 4+>K[↔MεKSMβ6K'π⊗c∃βπ⊗;W7↔w!β¬β⊗+π1βw+7↔∩β[π3.)β↔';↔↔9β↓βπ;"↓E9↓¬##∀4V≠#π;≡)βS#∂!βS#*β[π3.)β3'/→β↔';↔↔9∧	βπ;"α	1βN1↓Aql	r	q
aβ'Mπ∪?W∨Fceα	l	84*/≠';≥¬⊃1β←*β∂π9π≠'7WfS∃β
β∪'∂*βK?3bqαπ≠&+IβSF)βCK}≠↔∪W⊗)β∂πf`4*Jr∩>6∀*ε1"BI1β←*β∂π9π≠πeβ&C∃β;.k↔Iε{9βSF)β∪'≡)β'Mβ	β'→β↓qwac	=Y1β⊃β'_hQE=YbZaqI{11β↔&→9↓α&C∃β≠␈∪7W3
αRJVt→"a=2I-Eβ>K[↔Mπ##∃βw+7↔∩β?9β&C∃β∪N)mβ' h+'Mε+GWπfceβ3N[↔3eπ#=β#∂3∃βπwIβ[πg+∃β≠⊗{5↓Eπ#=↓Yph(4*
β7?K*β∂?7εc'∂π&+⊃βK∞s∪?5π≠gOS.iβS=π≠'7WfS∃βO→βπ9εS?5ε{→β¬π∪π∪'}∂S'6(4+↔f+7↔;"q↓αO∂Iβ'QεCπMβ
↓E∃β≡Cπ;∂*β?→β&+∂πgNs≥β'rβ↔π∂BβO↔∂}s⊃1βN1β'QεCπMβv{P4+∞cK↔π'Iβ∪?v)βO=r↓αS#∂!β'MbβS#∃ε≠#π;≡)β'Qε#↔∂πO→β'9π##∃β6KKOQπ≠↔∂?v!β'LhQA9A
q↓αSF)β∂#∞s∂∃βO!β∪↔≡gMβNqβS#*βO↔∂}s⊃βO.≠?;⊃εKM↓As↓Eβ?2βS#∃π∪↔7πNs';≤hQee=↓Aβ?2βS#∃π#'7∃bβ?I↓αqAEαB↓A9eJq↓αSF)β∂#∞s∂∃βO!β∪↔≡gMβNqβS#*β:{S@h+O↔≡{;⊃βO→βS#.q↓A9KJ{95
αa↓As↓E9↓∧K→β?/⊃βKπv#?5βw+7↔∩β∨↔;/∪πS?⊂h*Jεt">6J,
1"aJβ∨'[/→βWMε	βK↔∞aβ;Wn∪↔IαBβ↔S>+↔9↓αβπ;⊃β	1β←*β∂π9ε≠?7C/#∃β∧hSS'7*βQβ≠␈⊃βS#*βπS?jβS=β&+∂πeε∪eβO/#S';:4+Qk	β'→β↓9eecjaqEXh+Qu∩β'→↓αqefy∪avaqk↓9eeXh+Qu~β'→↓αqefy≠avaqk↓9efs⊃1β↔&→84(hRSπ/Ns≥β3};πK'&C7M1π;∃βO.(4+Qk	β'→β	yuβf{≡a?f{≥A9KI↓y↓h+Qu∩β'→↓∪quβ3}:a?3}9A9eJ↓y↓DhSQuMεK→↓Msiβ3?=A?3?;↓9eeβq↓I1ε+S
8hP4+←*β∂π9π+O∃β&C∃β≠␈∪7W3
βQuβ'∪W;∂∂#∃#3}:a?3}9A9eJI↓-↓λh(4*&yβO'o+3πS*βπ9β/3↔;Qπ##πQεCπMβπ∪?π⊗K3'SJαAβ?2β?∂∂/∪K';:aβ∨↔v+KπS*β¬βK∞s∪?4hSK↔πbβ;W7⊗+IαaεK9βSF)βKπv;∃↓%rqEmβ&C∃β↔6+;Qβ}≠∂WK~β'→αCbA9↓∧3S↔⊗sπS'6+3e0hS∨↔;/∪πS∃ε	βKπv#?5βNsS↔∨/⊃αaβNqβS#*βKπ;>)↓A9tjεb&u!mβSF)β↔[.sQβ?≡≠WKMεK_4*CbA*6
B&:Qr↓4(hRS#↔⊗)β'Mεs=αC∂≠∂π1π≠Sπ;&K⊃β⊗;∪?jβ;W7⊗+Iβ∨.s↔Kπ&{I9↓∧kπ;e¬βπO∂∞aβOg∨#↔7LhS';∂g+∪∃β}s∃βπv!βWO/∪MβOF{W3⊃ε{K∪'vK'3JβCK↔6+IβO.≠!β¬α∪∂↔K&K≠'↔"⊃βKπv#?44VsW7/⊃β∨↔v+KπS␈⊃βS=ε	β#?n)β7π&)β?;*q↓αSF)βSgεK∂π1π∪π;∪}iβ;Wn∪↔Iβ>+;↔K∂#?H4W∪↔GWO∪↔Mβ
βOSπ↔#';≥π3π3W*aβ∂πfc↔⊃β
βO↔↔"aβ←#N≠!β∪/#↔K7Ns↔Mβ&C∃βO/W↔;≡)β?_hSOW≡+GW↔w!β[πg+↔M9αα'→β&C∃βO∞k∃βC⊗{∨Kπjβ'Mβ↔+9β¬π≠↔∂?v!βS'n)β←'&AβS#*βOπ7(h+O↔.!1βSF)βOπn)βK↔∨+3SMπ;'31ε∪∃β≠␈+;⊃1π≠=βSzβ∂πK↔Iβ?W"βOSπ&KOS'≡33dhS';∪/β↔;∪.sQβ↔F+∂WSN{;M1ε+π∂!π#'7∃π##∃βπ∪?∨K∞iβ'Mπ∪W91ε	β;↔:βO↔↔"βO#?.c⊃β(h+WO.!9↓α&C∃βO.+⊃βOF{W3⊃ε∪∃βK.≠?K∪.!1βOzβS#π"β'→β↔+∨Mβ∂∪∃β≠␈+;⊃β␈⊃βOW∨β↔∂S. 4+SF)βCK};Kπ5ε≠π9β⊗)βKWrβπ∨πNqβW;&+Iβ'&+;S'≡1β∂}s∪'SN{;M8hP4*¬π#gC'≡1βC⊗{∨Kπnk';≥ε≠3'∂F)β≠?∩βWO'v9β¬β≡+↔∪↔"βKπ;&{5β;.k↔Iε;↔;↔⊗S?IεKMh4Ph(&J,
⊃"N,*⊃%lhP&↑JM"⊗29B∩N⊗⊗#i	1α≤*⊗⊃%Xh(&aSjN⊗⊗#X4(&<B&2∃αq99α$x4($L∩⊗≡&ph($&∀
:∩>jBa%lhP$&C⊗{∂↔O~βKπ;&{5β;.k↔I¬@4($L*:⊂4Ph(2'QεKMβ;␈!β?K&K;πKNcgQβε{OO'⊗c∃βSzβ∨↔;/∪πS∃π#KW3JβKπ;&{5β;.k↔K~β?9βλh+∂?↔∪↔∂SgIβ?C/∪πS'v9β∂?oβWS↔∪Yβ←∃π≠πS'≡3eβ?/∪O↔36+MβJβ∨↔;/∪πS'v9βO↔∂+↔;∂/_4+SFQβ7.+Qβ7␈≠QβO&S'O&K∂π1π#↔OS~β≠?Iπ∪π;∪}k;↔O~aβ3'↑)βS#*βK↔G.KK↔7.sQβSFP4+Nqβ¬βfK∨∃π#K'πbaβ;↔∂∪3eβ/Wπ1ε3Kπ∂&K?;Mε{→βSF)βKπv#?5βw+7↔↔→β≠πfaβ'9ε+π∂ hSC↔K≡+;Qβ}1βS#possible range.  The typical method, using an integer X is

	X:= (X * K1)MOD K2
where K1 and K2 are carefully selected constants.  A builtin random number
generator usually uses double precision integer arithmetic, so it can not
easily be programmed in standard Pascal.  To demonstrate the pattern of
behavior, here is the sequence of random numbers if K1 = 23, K2 = 100, and
the see is 47:

81 63 49 27 21 83 09 07 61 03

69 87 01 23 29 67 41 43 89 47

81 63 etc.

Among the flaws of this choice, the sequence repeats after generating only
twenty numbers, and it generates only numbers that end in 1,3,7, or 9.  If
the seed had been 25, the sequence would have been 25 75 25 75 25, etc.  By
choosing K1=    , K2=    , however, we could guarantee that every number
between 1 and     would be generated  once before repeating, for any seed
in that range.

If you must build your own random number generator, see Knuth, Vol.2, pg  ,
for some rules of thumb which ensure good performance.

Here is a Pascal program using an integer random number procedure to
simulate a dice game.  Player 1 rolls a die once, then player 2 rolls it
twice, player 1 rolls it three times, etc., until someone rolls a 6.  The
program simulates the game a number of times to estimate the probability
that A wins the game.

     CONSTANT C=MAXINT/6
     READ(SEED, NUMTRIALS)
     X:=SEED;
     WINS:=0;
     FOR I:=1 TO NUMTRIALS DO
	BEGIN
	PLAYER:=1;
	CHANGE:=1;
	DIE:=0;
	COUNTER:=0;
	WHILE DIE <> 6 DO
	     BEGIN
	     RANDOMM(X);
	     DIE:=X DIV C + 1;
	     COUNTER:= COUNTER + 1;
	     IF COUNTER = CHANGE THEN
		BEGIN
		COUNTER:=0;
		CHANGE:=CHANGE + 1;
		PLAYER:=3 - PLAYER;
		END
	     END;
	IF PLAYER =1 THEN WINS:= WINS + 1
	END;
	WRITELN(`PLAYER 1 WINS', WINS, `OUT OF', NUMTRIALS);
	WRITELN(`FOR AN ESTIMATED PROBABILITY', WINS/NUMTRIALS);
	WRITELN(`SEED WAS', SEED)

Exercise:

Simulate an island populated by wolves and rabbits.  The island is square,
and looks very much like a 50-by-50 array of regions.  Each region of the
island may be empty, or contain a wolf or a rabbit.  At each day, each wolf
has a 25% probability of moving to any adjacent wolf-free region, eating
any rabbit found there.  Rabbits have a 25% probability of moving to any
adjacent empty region.  Rabbits have a 5% probability per day of
reproducing ****fill in****.  A wolf starves if it has not eaten a rabbit
for     days.  Wolves have a       probability per day of reproducing.

Simulate the population of the island for 1000 days, printing a map showing
locations of the animals every 200th day, and tabulating the populations at
10 day intervals.  Initially, place about 10 wolves and 500 rabbits at
random.